import React from "react";

import { API } from "../../utils/api";
import { Link } from 'react-router-dom'
import { Toast } from "antd-mobile-v2";
import NavHeader from "../../components/Headnavbar";
import styles from './index.module.css'//使用CSSmodule
import { BASE_URL } from "../../utils/url";
import HouseItem from "../../components/houseList";
import withHook from "../../utils/Withhook";

class Map extends React.Component{  
    state = {
        // 小区下的房源列表
        housesList: [],
        // 表示是否展示房源列表
        isShowList: false
      }
    //生命周期开始
    componentDidMount(){
        this.initmap();//初始化地图
    }

    initmap(){
        //初始化地图这个对象为百度地图api提供
        //react脚手架要求全局对象使用window进行访问，不然ESlist校验错误
        const map = new window.BMap.Map("container")//初始化地图在id为container的容器内
        this.map = map// 作用：能够在其他方法中通过 this 来获取到地图对象
        //获取本地存储中，当前城市信息
        const {label,value} = JSON.parse(localStorage.getItem("hkzf_city"))//label是地址，value为区域id参数
        //创建地址解析器
        const myGeo = new window.BMap.Geocoder();
        //地址解析结果显示在地图上，并调整视野
        //地址解析 ，从地址到经纬度使用 getPoint,label为地址，point为响应的经纬度
        myGeo.getPoint(label,async point=>{
            if(point){
                //初始化地图
                map.centerAndZoom(point,11);//地图中心点显示（经纬度为中心）及展示级别
                map.addOverlay(new window.BMap.Marker(point));//创建覆盖物，标记当前坐标
                //添加地图2控件
                map.addControl(new window.BMap.NavigationControl());//地图缩放控件
                map.addControl(new window.BMap.ScaleControl());//比例尺控件
                this.renderOverlays(value)//渲染物入口（参数为区域id，刚开始为一级区域）
                //绑定移动事件，移动地图，房源信息列表消失
                map.addEventListener("movestart",()=>{
                    if(this.state.isShowList){
                        this.setState({
                            isShowList:false
                        })
                    }
                })
                    }
        },label);
    }

    //功能函数1：渲染覆盖物入口
    // 1 接收区域 id 参数，获取该区域下的房源数据
    // 2 判断获取房源类型以及下级地图缩放级别
    async renderOverlays(id) {
        Toast.loading("加载中",0,null,false)//开启等待 
        const res = await API.get(`/area/map?id=${id}`)//调用API获取区域信息
        Toast.hide();//关闭等待
        const data = res.data.body//获取当前级别下的区域信息（小区为房源信息，大区和镇为下级区域信息）

        // 调用 getTypeAndZoom 方法判断 下一区域级别 和当前区域覆盖物类型，以此来判断需要如何渲染覆盖物
        const { nextZoom, type } = this.getTypeAndZoom()
        // 创建区域覆盖物（每一个覆盖物信息，下一级别区域缩放大小，当前覆盖物形状）
        data.forEach(item => {
          this.createOverlays(item, nextZoom, type)
        })}
    
    //功能函数2：计算要绘制的覆盖物类型和下一个缩放级别
    // 大区   -> 11 ，范围：>=10 <12 ,cycle
    // 镇   -> 13 ，范围：>=12 <14,cycle
    // 小区 -> 15 ，范围：>=14 <16,rect

    getTypeAndZoom() {
        const zoom = this.map.getZoom()// 调用地图的 getZoom() 方法，来获取当前缩放级别
        let nextZoom, type//获取下一级别区域的缩放级别，以及当前的缩放形状
            if (zoom >= 10 && zoom < 12) {
            nextZoom = 13
            // circle 表示绘制圆形覆盖物（区、镇）
            type = 'circle'
            } else if (zoom >= 12 && zoom < 14) {
            // 镇 2级区域
            nextZoom = 15
            type = 'circle'
            } else if (zoom >= 14 && zoom < 16) {
            // 小区 3级区域（没有下一级）
            type = 'rect'}
            return {nextZoom,type}
        }
        
    //功能函数3：选择创建覆盖物的类型
    createOverlays(data, zoom, type) {
        const {
        coord: { longitude, latitude },//当前经纬度
        label: areaName,//当前区域名称
        count,//区域覆盖物数量
        value//区域id
        } = data

        // 创建经纬度坐标对象
        const areaPoint = new window.BMap.Point(longitude, latitude)

        if (type === 'circle') {
        // 根据当前的形状信息，创建区或镇覆盖物
        this.createCircle(areaPoint, areaName, count, value, zoom)
        } else {
        // 根据当前的形状信息，创建小区覆盖物
        this.createRect(areaPoint, areaName, count, value)
        }
    }

    //函数4
    //创建大区、镇覆盖物
    createCircle(point, name, count, id, zoom) {
        // 创建覆盖物，内部不包含文字
        const label = new window.BMap.Label('', {
        position: point,//坐标位置
        offset: new window.BMap.Size(-35, -35)//覆盖物偏移
        })
        label.id = id// 给 label 对象添加一个唯一标识
        label.setContent(`
        <div class="${styles.bubble}">
            <p class="${styles.name}">${name}</p>
            <p>${count}套</p>
        </div>
        `) // 设置房源覆盖物内容

        // 添加单击事件
        label.addEventListener('click', () => {
        // 调用 renderOverlays 方法，获取该区域下的房源数据
        this.renderOverlays(id)
        // 放大地图，以当前点击的覆盖物为中心放大地图
        this.map.centerAndZoom(point, zoom)
        // 解决清除覆盖物时，百度地图API的JS文件自身报错的问题
        setTimeout(() => {
            // 清除旧覆盖物信息
            this.map.clearOverlays()
        }, 0)
        })

        // 添加新覆盖物到地图中
        this.map.addOverlay(label)
    }

    //功能函数5：创建小区覆盖物
    createRect(point, name, count, id) {
        // 创建覆盖物
        const label = new window.BMap.Label('', {
          position: point,
          offset: new window.BMap.Size(-50, -28)
        })
        label.id = id// 给 label 对象添加一个唯一标识   
        label.setContent(`
          <div class="${styles.rect}">
            <span class="${styles.housename}">${name}</span>
            <span class="${styles.housenum}">${count}套</span>
            <i class="${styles.arrow}"></i>
          </div>
        `)// 设置房源覆盖物内容
    
        // 添加单击事件
        label.addEventListener('click', (e) => {
          this.getHousesList(id);
          //点击时，移动到成中心点
          const target = e.changedTouches[0]
          this.map.panBy(
            window.innerWidth / 2 - target.clientX,
            (window.innerHeight - 330) / 2 - target.clientY
          )

        })
        // 添加覆盖物到地图中
        this.map.addOverlay(label)
      }

    //函数6
    // 小区点击触发，获取小区房源数据
    async getHousesList(id) {
        Toast.loading("加载中",0,null,false)
        const res = await API.get(`/houses?cityId=${id}`)
        Toast.hide()
        this.setState({
        housesList: res.data.body.list,
        // 展示房源列表
        isShowList: true
        })
    }
    //渲染函数1，渲染房屋列表
    renderHousesList() {
        return this.state.housesList.map(item => (  
            <HouseItem
              key={item.houseCode}//房屋序列号作为key使用
              src={BASE_URL + item.houseImg}//房屋照片
              title={item.title}//标题
              desc={item.desc}////房屋信息
              tags={item.tags}////房屋标签
              price={item.price}//房屋价格
              onClick={()=>this.props.to(`/detail/${item.houseCode}`)}//点击事件
            />
          ))
    }

    render(){
        return <div className={styles.map}>
            {/* 1顶部导航 */}
            <NavHeader title={"地图找房"}/>
            {/* 2地图容器 */}
            <div id="container" className={styles.container}></div>
            {/* 3房源列表 */}
                {/* 房屋列表 顶部 */}
            <div className={[styles.houseList,this.state.isShowList ? styles.show : ''].join(' ')}>
                {/* 房屋列表 头部 */}
                <div className={styles.titleWrap}>
                    <h1 className={styles.listTitle}>房屋列表</h1>
                    <Link className={styles.titleMore} to="/home/list">
                    更多房源
                    </Link>
                </div>
                {/* 房屋列表 详细内容 */}
                <div className={styles.houseItems}>
                    {this.renderHousesList()}
                </div>
            </div>
        </div>
    }
}

const MapHook= withHook(Map)
export default MapHook